﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BulletHellBoxes.GameObjects.Player;
using BulletHellBoxes.Utilities;

using FlatRedBall;
using FlatRedBall.Graphics;
using FlatRedBall.Screens;
using FlatRedBall.Graphics.Animation;

using Microsoft.Xna.Framework.Audio;

namespace BulletHellBoxes.Screens
{
    public class GameScreen : Screen
    {
        #region Fields
        private Player _player1;
        private Player _player2;

        private Sprite _background;

        private Sprite _winDoors;
        private Sprite _winText;
        private Sprite _swapText;

        private bool _win;
        private bool _winDoorTrigger;
        private bool _winTextTrigger;
        private bool _openDoorTrigger;
        private bool _swapRolesTrigger;
        private int _winner;
        private bool _scored;

        private SoundEffect _endRoundSound;
        private SoundEffect _doorSlideSound;
        private SoundEffect _doorImpactSound;

        private double _textTime;
        #endregion

        #region Methods

        #region Constructor and Initialize

        public GameScreen()
            : base("GameScreen")
        {
            // Don't put initialization code here, do it in
            // the Initialize method below
            //   |   |   |   |   |   |   |   |   |   |   |
            //   |   |   |   |   |   |   |   |   |   |   |
            //   V   V   V   V   V   V   V   V   V   V   V

        }

        public override void Initialize(bool addToManagers)
        {

            if (addToManagers)
            {
                AddToManagers();
            }

            _endRoundSound = FlatRedBallServices.Load<SoundEffect>(@"Content\Sounds\EndRound");
            _doorSlideSound = FlatRedBallServices.Load<SoundEffect>(@"Content\Sounds\DoorSlide");
            _doorImpactSound = FlatRedBallServices.Load<SoundEffect>(@"Content\Sounds\DoorImpact");

        }

        public override void AddToManagers()
        {
            string contentManagerName = "Global";
            // Change the font to a custom font from dafont.
            _player1 = new Player(true, 1);
            _player2 = new Player(false, 2);

            _background = SpriteManager.AddSprite(@"/Content/GameObjects/Background/background");
            _background.PixelScale();
            _background.Z = -0.1f;

            _winDoors = SpriteManager.AddSprite(InitializeDoors());
            _winDoors.Animate = false;
            _winDoors.Visible = false;
            _winDoors.Z = 0.2f;
            _winDoors.PixelScale();

            _winText = SpriteManager.AddSprite(InitializeText());
            _winText.Animate = false;
            _winText.Visible = false;
            _winText.Z = 0.3f;
            _winText.PixelScale();

            _swapText = SpriteManager.AddSprite(InitializeSwap());
            _swapText.Animate = false;
            _swapText.Visible = false;
            _swapText.Z = 0.3f;
            _swapText.PixelScale();

            _win = false;
            _winDoorTrigger = false;
            _winTextTrigger = false;
            _swapRolesTrigger = false;
            _scored = false;
            _winner = 0;

            _textTime = 0.0;
        }


        #endregion

        #region Public Methods

        public override void Activity(bool firstTimeCalled)
        {
            base.Activity(firstTimeCalled);

            if (!firstTimeCalled)
            {

                if (!_win)
                {
                    _player1.Activity();
                    _player2.Activity();

                    HandleCollisions();
                }
                else
                {
                    if (!_winDoorTrigger)
                    {
                        _doorSlideSound.Play();
                        _doorImpactSound.Play();

                        _winDoors.Visible = true;
                        _winDoors.CurrentFrameIndex = 0;
                        _winDoors.CurrentChainIndex = 0;
                        _winDoors.Animate = true;
                        _winDoorTrigger = true;

                        _player1.Paused = true;
                        _player2.Paused = true;
                    }
                    else if (!_winTextTrigger)
                    {
                        if (_winDoors.JustCycled)
                        {
                            _endRoundSound.Play();

                            _winDoors.Animate = false;
                            _winDoors.CurrentChainIndex = 1;
                            _winDoors.CurrentFrameIndex = 0;

                            _winText.Visible = true;
                            _winText.CurrentChainIndex = _winner - 1;
                            _winTextTrigger = true;
                            _winText.Animate = true;
                            _textTime = TimeManager.CurrentTime;
                        }
                    }
                    else if (!_openDoorTrigger && !_swapRolesTrigger)
                    {
                        if (_winText.JustCycled)
                        {
                            _winText.Animate = false;
                            _winText.Visible = false;

                            if (_scored)
                            {
                                _doorSlideSound.Play();

                                _openDoorTrigger = true;
                                _winDoors.Animate = true;
                            }
                            else
                            {
                                _swapRolesTrigger = true;
                                _swapText.Visible = true;
                                _swapText.Animate = true;
                            }
                        }
                        
                    }
                    else if (_swapText.JustCycled && !_openDoorTrigger)
                    {
                        _swapText.CurrentFrameIndex = 0;
                        _swapText.Visible = false;
                        _openDoorTrigger = true;
                        _winDoors.Animate = true;
                    }
                    else if (_winDoors.JustCycled)
                    {
                        _winDoors.Visible = false;
                        _winDoors.Animate = false;
                        _win = false;
                        _player1.Paused = false;
                        _player2.Paused = false;
                        _player1.Reset();
                        _player2.Reset();
                        _winDoorTrigger = false;
                        _winTextTrigger = false;
                        _openDoorTrigger = false;
                        _swapRolesTrigger = false;
                    }

                }
            }
        }

        public override void Destroy()
        {
            base.Destroy();

        }

        #endregion

        #region Private Methods
        private void HandleCollisions()
        {
            CollisionType result;

            // check to see if player 2 is colliding with player 1 or bullets
            result = _player1.CollideWith(_player2);

            if (result == CollisionType.None)
            {
                // Player 1 - Attacker; Player 2 Defender

                // check to see if player 1 is colliding with player 2 or bullets
                result = _player2.CollideWith(_player1);
                if (result == CollisionType.Win)
                {
                    // Player 1 Wins - Swap Roles
                    _player1.SwapRole();
                    _player2.SwapRole();
                    _win = true;
                    _winner = 1;
                    _scored = false;
                }
                else if (result == CollisionType.Hit)
                {
                    // Player 1 Hit - Player 2 Gets Point
                    _player1.UpdateScore(false);
                    _player2.UpdateScore(true);
                    _win = true;
                    _winner = 2;
                    _scored = true;
                }
            }
            else
            {
                // Player 2 - Attacker; Player 1 - Defender
                if (result == CollisionType.Win)
                {
                    // Player 2 Wins - Swap Roles
                    _player1.SwapRole();
                    _player2.SwapRole();
                    _win = true;
                    _winner = 2;
                    _scored = false;
                }
                else if (result == CollisionType.Hit)
                {
                    // Player 2 Loses - Player 1 Gets Point
                    _player1.UpdateScore(true);
                    _player2.UpdateScore(false);
                    _win = true;
                    _winner = 1;
                    _scored = true;
                }
            }
        }


        protected AnimationChainList InitializeDoors()
        {
            // Loads the animation chain for when the buckle opens.
            AnimationChainList ani = new AnimationChainList();
            AnimationChain open = new AnimationChain();
            AnimationChain close = new AnimationChain();

            for (int i = 1; i <= 15; i++)
            {
                close.Add(new AnimationFrame(@"Content/GameObjects/Transition/Doors/Close/" + i, 0.06f, "Global"));
            }
            close.Name = "close";

            for (int i = 1; i <= 5; i++)
            {
                open.Add(new AnimationFrame(@"Content/GameObjects/Transition/Doors/Open/" + i, 0.06f, "Global"));
            }
            open.Name = "open";

            ani.Add(close);
            ani.Add(open);

            return ani;
        }

        protected AnimationChainList InitializeText()
        {
            // Loads the animation chain for when the buckle opens.
            AnimationChainList ani = new AnimationChainList();
            AnimationChain p1 = new AnimationChain();
            AnimationChain p2 = new AnimationChain();

            for (int i = 1; i <= 42; i++)
            {
                p1.Add(new AnimationFrame(@"Content/GameObjects/Transition/P1Wins/" + i, 0.06f, "Global"));
                p2.Add(new AnimationFrame(@"Content/GameObjects/Transition/P2Wins/" + i, 0.06f, "Global"));
            }

            p1.Name = "p1";
            p2.Name = "p2";

            ani.Add(p1);
            ani.Add(p2);

            return ani;
        }

        protected AnimationChainList InitializeSwap()
        {
            // Loads the animation chain for when the buckle opens.
            AnimationChainList ani = new AnimationChainList();
            AnimationChain swap = new AnimationChain();

            for (int i = 1; i <= 42; i++)
            {
                swap.Add(new AnimationFrame(@"Content/GameObjects/Transition/Switch/" + i, 0.06f, "Global"));
            }

            swap.Name = "swap";

            ani.Add(swap);

            return ani;
        }

        #endregion

    }

        #endregion
}
